import os.path
import time
import xlwt
import xlrd
import xlutils
from xlutils.copy import copy
import threading
import queue
import tkinter


created_flag = 1
deleted_flag = 2
modified_flag = 3
visited_flag = 4
no_changed = 0
start_stop = False
save_list = []


def get_visit_status(monitor_path,snapshot):
    visit_status = []
    for i in snapshot:
        path = monitor_path + "/" + i
        visit_status.append(time.ctime(os.path.getatime(path)))
    return visit_status


def get_lastmodified_status(monitor_path,snapshot):
    modify_status = []
    for i in snapshot:
        path = monitor_path + "/" + i
        modify_status.append(time.ctime(os.path.getmtime(path)))
    return modify_status
    

def even_created(snapshot,monitor_path):
    global no_changed,created_flag
    temp_snapshot = os.listdir(monitor_path)
    created_dic = {} # 键是文件名，值为新建的时间
    if temp_snapshot != snapshot:
        for i in temp_snapshot:
            if i not in snapshot:
                path = monitor_path + "/" + i
                created_dic[i] = time.strftime("%m-%d~%H:%M",time.localtime())
        return created_flag,created_dic
    return no_changed,created_dic


def even_deleted(snapshot,monitor_path):
    global no_changed,deleted_flag
    temp_snapshot = os.listdir(monitor_path)
    deleted_dic = {} # 键为文件名，值是删除的时间
    if temp_snapshot != snapshot:
        for i in snapshot:
            if i not in temp_snapshot:
                path = monitor_path + "/" + i
                deleted_dic[i] = time.strftime("%m-%d~%H:%M",time.localtime())
        return deleted_flag,deleted_dic
    return no_changed,deleted_dic


def even_modify(snapshot,modify_status,monitor_path):
    global no_changed,modified_flag
    flag = False
    modified_dic = {}
    temp_snapshot = os.listdir(monitor_path)
    temp_modify_status = get_lastmodified_status(monitor_path, temp_snapshot)
    for i in temp_snapshot:
        if i in snapshot:
            index_old = snapshot.index(i)
            index_new = temp_snapshot.index(i)
            if modify_status[index_old] != temp_modify_status[index_new]:
                flag = True
                modified_dic[i] = temp_modify_status[index_new]
    if flag:
        return modified_flag,modified_dic
    return no_changed,modified_dic


def even_visit(snapshot,visit_status,monitor_path):
    global no_changed,visited_flag
    flag = False
    visited_dic = {}
    temp_snapshot = os.listdir(monitor_path)
    temp_visit_status = get_visit_status(monitor_path, temp_snapshot)
    for i in temp_snapshot:
        if i in snapshot:
            index_old = snapshot.index(i)
            index_new = temp_snapshot.index(i)
            if visit_status[index_old] != temp_visit_status[index_new]:
                flag = True
                visited_dic[i] = temp_visit_status[index_new]
    if flag:
        return visited_flag,visited_dic
    return no_changed,visited_dic
    

# def save_path_init(save_path):
#     save = xlwt.Workbook(encoding="utf-8",style_compression=0)# 创建workbook对象，指定编码格式和样式压缩
#     sheet = save.add_sheet("系统文件监控日志",cell_overwrite_ok=True)# 创建表，表名，和是否覆盖
#     title = ["事件","涉及文件","操作时间"]
#     for i in range(len(title)):
#         sheet.write(0,i,title[i]) # write写入信息
#     save.save(save_path)
#     return True


def save_to_sheet(save_path):
    global save_list
    save = xlwt.Workbook(encoding="utf-8",style_compression=0)# 创建workbook对象，指定编码格式和样式压缩
    sheet = save.add_sheet("系统文件监控日志",cell_overwrite_ok=True)# 创建表，表名，和是否覆盖
    title = ["事件","涉及文件","操作时间"]
    for i in range(len(title)):
        sheet.write(0,i,title[i]) # write写入信息
    if len(save_list):
        for i in range(0,len(save_list)):
            for j in range(len(save_list[i])):
                sheet.write(i+1,j,save_list[i][j])

    save.save(save_path)


def dic_to_list(flag,even_dic):
    global save_list
    app_list = ['','新建文件','删除文件','修改文件','访问文件']
    temp_save = []
    for key,value in even_dic.items():
        temp_save.append(app_list[flag])
        temp_save.append(key)
        temp_save.append(value)
        save_list.append(temp_save)


def monitor_loop(snapshot,visit_status,modify_status,monitor_path,save_path):
    global start_stop,save_list
    while start_stop:
        _created_flag,even_dic_c = even_created(snapshot, monitor_path)
        _deleted_flag,even_dic_d = even_deleted(snapshot, monitor_path)
        _modified_flag,even_dic_m = even_modify(snapshot, modify_status, monitor_path)
        _visited_flag,even_dic_v = even_visit(snapshot, visit_status, monitor_path)
        if _created_flag:
            dic_to_list(_created_flag, even_dic_c)
        if _deleted_flag:
            dic_to_list(_deleted_flag, even_dic_d)
        if _modified_flag:
            dic_to_list(_modified_flag, even_dic_m)
        if _visited_flag:
            dic_to_list(_visited_flag, even_dic_v)
        snapshot = os.listdir(monitor_path)
        modify_status = get_lastmodified_status(monitor_path, snapshot)
        visit_status = get_visit_status(monitor_path, snapshot)
        time.sleep(0.5)
            # snapshot = temp_snapshot
    return


def start(monitor_path):
    global start_stop
    while 1:
        os.system("clear")
        flag = input(f"键入start开始监控{monitor_path}！")
        if flag == 'start':
            os.system("clear")
            print(f"正在监控{monitor_path}！")
            start_stop = True
            return
        else:
            os.system("clear")
            print("键入错误，请重新键入")
            time.sleep(1)
        

def stop(monitor_path):
    global start_stop
    os.system("clear")
    flag = input(f"正在监控{monitor_path}！\n键入stop结束监控！")
    if flag == 'stop':
        os.system("clear")
        print("退出监控！已生成日志文件")
        start_stop = False
        return
    else:
        os.system("clear")
        print("键入错误，请重新键入")
        time.sleep(1)
        
# todo 做图形化界面，要重新设计一下开始和结束的接口和主循环接入口
def Graphical(monitor_path):
    top = tkinter.Tk()
    top.title("系统文件监控")
    top.geometry('500x300')
    top.resizable(0,0)
    start_button = tkinter.Button(top,text="start",command=main(),bd=1,font=('Helvetica', 30))
    stop_button = tkinter.Button(top,text="stop",bd=1,font=('Helvetica', 30))
    start_label = tkinter.Label(top,text="点击start开始监控!",width=20,font=('Helvetica', 25))
    position_label = tkinter.Label(top,text=monitor_path,width=43,font=('Helvetica', 12))
    start_label.place(x=60,y=30)
    position_label.place(x=48,y=100)
    start_button.place(x=85,y=200)
    stop_button.place(x=300,y=200)
    top.mainloop()


def main():
    global start_stop,save_list
    local_time = time.strftime("%m-%d~%H:%M",time.localtime())
    monitor_path = "/home/Codes/python/网络安全课程设计_Y/test"
    save_path = f"/home/Codes/python/网络安全课程设计_Y/monitor{local_time}.xls"
    started = threading.Thread(target=start,args=(monitor_path,))
    started.start()
    started.join() # 成功开始
    snapshot = os.listdir(monitor_path) # 快照
    visit_status = get_visit_status(monitor_path, snapshot) # 上次访问时间
    modified_status = get_lastmodified_status(monitor_path, snapshot) # 上次修改时间
    loop = threading.Thread(target=monitor_loop,args=(snapshot,visit_status,modified_status,monitor_path,save_path))
    stoped = threading.Thread(target=stop,args=(monitor_path,))
    loop.start()
    stoped.start()
    loop.join()
    stoped.join()# 监控结束
    save_to_sheet(save_path) #结果保存到表格文件中


def test():
    monitor_path = "/home/Codes/python/网络安全课程设计_Y/test"
    Graphical(monitor_path)


if __name__ == "__main__":
    # test()
    main()
    